<template>
  <el-select
    v-if="!isRemote"
    ref="elInput"
    v-model="valueModel"
    style="width: 100%"
    v-bind="props"
    v-on="$listeners"
    @change="handleChange"
  >
    <el-option
      v-for="item in computedOptions"
      :key="item[valueKey]"
      v-bind="item"
      :label="item[labelKey]"
      :value="item[valueKey]"
      :disabled="item[disabledKey]"
    />
  </el-select>
  <el-select
    v-else
    ref="elInput"
    v-model="valueModel"
    style="width: 100%"
    v-bind="props"
    v-on="$listeners"
    @change="handleChange"
  >
    <el-option
      v-for="item in remoteOptions"
      :key="item[valueKey]"
      v-bind="item"
      :label="item[labelKey]"
      :value="item[valueKey]"
      :disabled="item[disabledKey]"
    />
  </el-select>
</template>

<script>
import Vue from 'vue';
import {Option, Select} from "element-ui";
import {cloneJson, toString} from "../../../../utils";
import {request} from "../../../../request";
Vue.use(Select);
Vue.use(Option);
/**
 * 下拉框
 * @author maolin
 */
export default {
  name: "ErpFormSelect",
  components: {
  },
  props: {
    /**
     * 标题
     * @public
     */
    title: {
      type: String,
      default: '',
    },
    /**
     * 字段
     * @public
     */
    field: {
      type: String,
      default: ''
    },
    /**
     * 值
     * @public
     */
    value: {
      type: [String,Number],
      default: null
    },
    /**
     * 选项
     * @public
     */
    options: {
      type: Array,
      default () {
        return [];
      }
    },
    /**
     * 选项
     * @public
     */
    props: {
      type: Object,
      default () {
        return {
        };
      }
    },
    /**
     * 表单对象
     * @public
     */
    form: {
      type: Object,
      default () {
        return {
        };
      }
    },
    /**
     * 额外配置
     * ```js
     * return {
          labelKey: 'label',
          disabledKey: 'disabled',
          remote: {
            enable: false,
            url: "",
            watchFields: ['id', 'userId'],
            query: {},
            // 额外表单对象，一般为主表对象
            extraData: {},
            // 额外请求参数，通常用于主从，主表通过extraQuery传递
            extraQuery: {},
            // 额外请求需要观察的field, 一般用于观察主表字段变化
            extraWatchFields: ['id'],
            // 请求参数函数
            queryFunction: "",
            // 返回函数，用于自定义设置返回格式
            resFunction: "",
            // 设置是否将list传递到form
            transmitList: {
              // 是否开启，默认关闭
              enable: false,
            },
          },
          relateFields: [
            {
              field: "userId",
            },
            {
              // 表单中需要的field
              field: "uid",
              // 弹窗列表中的field， 若不传relateField，则将form中的uid清为null
              relateField: "id"
            }
          ],

        };
     * ```
     * @public
     */
    extra: {
      type: Object,
      default () {
        return {
          labelKey: 'label',
          disabledKey: 'disabled',
          remote: {
            enable: false,
            url: "",
            watchFields: ['id', 'userId'],
            query: {},
            // 额外表单对象，一般为主表对象
            extraData: {},
            // 额外请求参数，通常用于主从，主表通过extraQuery传递
            extraQuery: {},
            // 额外请求需要观察的field, 一般用于观察主表字段变化
            extraWatchFields: ['id'],
            // 请求参数函数
            queryFunction: "",
            // 返回函数，用于自定义设置返回格式
            resFunction: "",
            // 设置是否将list传递到form
            transmitList: {
              // 是否开启，默认关闭
              enable: false,
            },
          },
          relateFields: [
            {
              field: "userId",
            },
            {
              // 表单中需要的field
              field: "uid",
              // 弹窗列表中的field， 若不传relateField，则将form中的uid清为null
              relateField: "id"
            }
          ],

        };
      }
    }
  },
  data () {
    return {
      initRemoteForm: {},
      remoteVisible: false,
      remoteOptions: [
      ]
    };
  },
  computed: {
    isRemote () {
      return !!(this.extra && this.extra.remote && this.extra.remote.enable && this.extra.remote.enable !== false);
    },
    computedOptions() {
      if (this.isRemote) {
        return [];
      } else {
        let options = cloneJson(this.options);
        if (options && options.length > 0) {
          for (let i in options) {
            options[i][this.valueKey] = toString(options[i][this.valueKey]);
          }
        }
        return options;
      }
    },
    multiple () {
      return this.props && this.props.multiple === true;
    },
    isIntegerValue () {
      return !!(this.options && this.options[0] && !isNaN(this.options[0][this.valueKey]));
    },
    valueModel: {
      get () {
        if (this.multiple) {
          return this.value ? this.value.split(',') : [];
        }
        return toString(this.value);
      },
      set (val) {
        if (this.multiple) {
          val = val ? val.join(',') : val;
        } else {
          // 只考虑单选
          if (this.extra && this.extra.relateFields && this.extra.relateFields.length > 0) {
            let relateFields = this.extra.relateFields;
            for (let i in relateFields) {
              let obj = {};
              if (relateFields[i].relateField) {
                let row = this.getItemByValue(val);
                obj[relateFields[i].field] = row && row[relateFields[i].relateField] ? row[relateFields[i].relateField] : null;
              } else {
                obj[relateFields[i].field] = null;
              }

              this.$emit('update-id-field', obj);
            }
          }
        }
        this.$emit('value-change', val);
      }
    },
    valueKey () {
      if (this.props && this.props.valueKey) {
        return this.props.valueKey;
      }
      return 'value';
    },
    labelKey () {
      if (this.extra && this.extra.labelKey) {
        return this.extra.labelKey;
      }
      return 'label';
    },
    disabledKey () {
      if (this.extra && this.extra.disabledKey) {
        return this.extra.disabledKey;
      }
      return 'disabled';
    },
    resFunction () {
      if (this.extra && this.extra.remote && this.extra.remote.resFunction) {
        return this.extra.remote.resFunction;
      }
      return '';
    },
    transmitList () {
      return this.extra && this.extra.remote && this.extra.remote.transmitList ? this.extra.remote.transmitList : null;
    }
  },
  watch: {
    form: {
      immediate:true,
      deep: true,
      handler (form) {
        let extraWatchFields = this.extra && this.extra.remote && this.extra.remote.extraWatchFields ? this.extra.remote.extraWatchFields : [];
        if (extraWatchFields && extraWatchFields.length > 0) {
          return false;
        }

        // 如果存储的表单【initRemoteForm】值和需要观察的表单【form】值不同，则进行异步数据查询， 并且将观察到的最新表单值保存到初始化用做存储表单。
        let initRemoteForm = this.initRemoteForm;
        let watchFields = this.extra && this.extra.remote && this.extra.remote.watchFields ? this.extra.remote.watchFields : [];
        let isChange = false;
        if (watchFields && watchFields.length > 0) {
          for (let i in watchFields) {
            if (initRemoteForm[watchFields[i]] === undefined) {
              initRemoteForm[watchFields[i]] = form[watchFields[i]];
              if (form[watchFields[i]]) {
                isChange = true;
              }
            }
            if (initRemoteForm[watchFields[i]] !== form[watchFields[i]]) {
              isChange = true;
              initRemoteForm[watchFields[i]] = form[watchFields[i]];
            }
          }
        }

        if (isChange) {
          console.log(isChange)
          this.generateRemoteOptions(form)
            .then(res => {
              if (!res || res.length === 0) {
                this.valueModel = null;
                this.remoteVisible = false;
              } else {
                this.remoteVisible = true;
                let flag = true;
                for( let i in res) {
                  console.log(res, 7998989)
                  if (res[i][this.valueKey] === this.valueModel) {
                    flag = false;
                  }
                }
                if (flag) {
                  this.valueModel = null;
                }
              }
              this.remoteOptions = res;

            })
            .catch(res => {
              this.remoteOptions = res;
              this.valueModel = null;
            });
        }
      }
    },
    "extra.remote.extraData": {
      immediate: true,
      deep: true,
      handler (form) {
        let watchFields = this.extra && this.extra.remote && this.extra.remote.extraWatchFields ? this.extra.remote.extraWatchFields : [];
        if (!watchFields || watchFields.length == 0) {
          return false;
        }
        // 如果存储的表单【initRemoteForm】值和需要观察的表单【form】值不同，则进行异步数据查询， 并且将观察到的最新表单值保存到初始化用做存储表单。
        let initRemoteForm = this.initRemoteForm;
        let isChange = false;
        if (watchFields && watchFields.length > 0) {
          for (let i in watchFields) {
            if (initRemoteForm[watchFields[i]] === undefined) {
              initRemoteForm[watchFields[i]] = form[watchFields[i]];
              if (form[watchFields[i]]) {
                isChange = true;
              }
            }
            if (initRemoteForm[watchFields[i]] !== form[watchFields[i]]) {
              isChange = true;
              initRemoteForm[watchFields[i]] = form[watchFields[i]];
            }
          }
        }
        if (isChange) {
          this.generateRemoteOptions(form)
            .then(res => {
              if (!res || res.length === 0) {
                this.valueModel = null;
                this.remoteVisible = false;
              } else {
                this.remoteVisible = true;
                let flag = true;
                for( let i in res) {
                  res[i][this.valueKey] = toString(res[i][this.valueKey]);
                  if (res[i][this.valueKey] === this.valueModel) {
                    flag = false;
                  }
                }
                if (flag) {
                  this.valueModel = null;
                }
              }
              this.remoteOptions = res;
            })
            .catch(res => {
              this.remoteOptions = res;
              this.valueModel = null;
            });
        }
      }
    },
    options (options) {
      if (options) {
        this.filterItem();
      }
    }
  },
  created() {
  },
  mounted() {
  },
  methods: {
    /**
     * 通过值获取下拉项中某一项
     * @private
     * @param val
     * @returns {null|*}
     */
    getItemByValue (val) {
      let options = this.computedOptions;
      if (this.isRemote) {
        options = this.remoteOptions;
      }
      if (options && options.length > 0) {
        for (let i in options) {
          if (options[i][this.valueKey] == val) {
            return options[i];
          }
        }
      }
      return null;
    },
    /**
     * 过滤下拉项
     * @private
     */
    filterItem () {
      let options = this.options;
      if (!options) {
        this.valueModel = '';
      } else {
        let flag = true;
        options.map(item => {
          if (item[this.valueKey] == this.value) {
            flag = false;
          }
        });
        if (flag) {
          this.valueModel = '';
        }
      }

    },
    /**
     * 获取焦点
     * @public
     */
    focus () {
      this.$refs.elInput.focus();
    },
    /**
     * 移除焦点
     * @public
     */
    blur () {
      this.$refs.elInput.blur();
    },
    /**
     * 获取远程请求的参数
     * @private
     * @param {object} form 表单项
     * @param {string} remoteUrl 请求远程数据的url
     * @returns {{}|null|*}
     */
    getRemoteQuery (form, remoteUrl) {
      let query = {};
      if (remoteUrl){
        if (this.extra.remote.queryFunction) {
          try{
            return new Function('form', 'field', this.extra.remote.queryFunction)(form, this.field);
          }catch (e) {
            console.log(e);
          }
        } else if (this.extra.remote.query){
          let row = cloneJson(this.extra.remote.query);
          for (let i in row) {
            if (typeof row[i] === 'string' && row[i].substr(0, 3) === '$f_' && row[i].length > 3) {
              let field = row[i].substr(3);
              if (form[field] !== undefined) {
                row[i] = form[field];
              }
            }
          }
          query = Object.assign(query, row);
        } else if (this.extra.remote.extraQuery) {
          let row = cloneJson(this.extra.remote.extraQuery);
          for (let i in row) {
            if (typeof row[i] === 'string' && row[i].substr(0, 4) === '$eq_' && row[i].length > 4) {
              let field = row[i].substr(4);
              if (form[field] !== undefined) {
                row[i] = form[field];
              }
            }
          }
          query = Object.assign(query, row);
        }
        return query;
      }
      return null;
    },
    /**
     * 值更新
     * @private
     * @param {*} e 值
     */
    handleChange (e) {
      console.log(e, "e")
      this.valueModel = e;
      this.$bus.$emit("selectChange", {value: e, form: this.form, options: this.options, field: this.field});
    },
    /**
     * 传递选项
     * @private
     * @param {object} options 选项
     * @returns {boolean}
     */
    transmitOptions (options) {
      const transmitList = this.transmitList;
      if (!transmitList) {
        return false;
      }
      if (transmitList.enable) {
        this.$emit('transmit-list', {options});
      }
    },
    /**
     * 生成远程选项
     * @private
     * @param {object} form 表单对象
     * @returns {Promise<unknown>}
     */
    generateRemoteOptions (form) {
      let remoteUrl = this.extra && this.extra.remote && this.extra.remote.enable && this.extra.remote.url ? this.extra.remote.url : '';
      return new Promise((resolve, reject) => {
        let options = [];
        if (!remoteUrl) {
          resolve(options);
          return options;
        }
        // request.post(remoteUrl, this.getRemoteQuery(form, remoteUrl))
        // .then(res => {
          let res = {
            code: 0,
            data: {
              default: "258",
              list: [
                {
                  "text": "吨",
                  "value": 258
                },
                {
                  "text": "KG",
                  "value": 296
                }
              ]
            }
          }
          console.log(this)
          options = res.data;
          // 配置回调格式
          if (this.resFunction) {
            try{
              options = new Function("res", this.resFunction)(res);
              if(res.data.default) {
                this.handleChange(res.data.default)
              }
            }catch (e) {
              console.log(e);
            }
          }
          // 配置是否需要将列表传递到表单
          this.transmitOptions(options);
          if (options && options) {
            for (let i in options) {
              options[i][this.valueKey] = toString(options[i][this.valueKey]);
            }
          }

          resolve(options);
          return options;
        // })
        // .catch(err => {
        //   reject(options);
        //   return options;
        // });
      });
    }
  }
};
</script>

<style scoped>

</style>
